package mt.omid.dimomuth.bus;


import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import sun.tools.tree.ThisExpression;


public class ExtMessage extends CBMessage
{

    /*****
     * Header byte mapping 
     * type 1-2 0 
     * sID 1-255 1 
     * sInst 1-255 2 
     * sPort 1-65535 3,4
     * sIP nnn.nnn.nnn.nnn 5,6,7,8 
     * rId 9
     * rInst 10 
     * rPort 11,12 
     * rIP 13,14,15,16 
     * isInternal 0-1 17 always 0
     * Length 0-65535 18,19
     * Data Part 
     */
    public int	      sId, sInst, sPort;
    public String	   sIP, rIP;
    public int	      rId, rInst, rPort;
    public int	      type;
    public boolean	  isInternal;
    public int	      len;

    /***
     * Data Part 20-20+len Data 20+len+1 End-Of-Message (EOM) 0
     */
    public byte []	  data;
//    private Object	  intrMsg;

    public final static int CB_MSG_TYPE_RES    = 1;
    public final static int CB_MSG_TYPE_REQ    = 2;

    public final static int CB_MSG_IS_INTERNAL = 1;

    public final static int HEADER_SIZE	= 20;


    public ExtMessage()
    {
	this.internal = false;
	this.isInternal = false;
    }

    public static ExtMessage decode( byte [] buf )
    {
	ExtMessage cbm = new ExtMessage();
	cbm.type = buf[ 0 ];
	cbm.sId = buf[ 1 ];
	cbm.sInst = buf[ 2 ];
	// cbm.sPort = buf[3] and buf[4];

	return cbm;
    }

    public static ExtMessage decode( InputStream in ) throws IOException
    {
	ExtMessage cbm = new ExtMessage();
	DataInputStream din = new DataInputStream( in );

	cbm.type = din.readByte();
	cbm.sId = din.readUnsignedByte();
	cbm.sInst = din.readUnsignedByte();
	cbm.sPort = din.readUnsignedShort();
	cbm.sIP = new String( din.readUnsignedByte() + "." + din.readUnsignedByte() + "."
		+ din.readUnsignedByte() + "." + din.readUnsignedByte() );
	cbm.rId = din.readUnsignedByte();
	cbm.rInst = din.readUnsignedByte();
	cbm.rPort = din.readUnsignedShort();
	cbm.rIP = new String( din.readUnsignedByte() + "." + din.readUnsignedByte() + "."
		+ din.readUnsignedByte() + "." + din.readUnsignedByte() );
	cbm.isInternal = din.readByte() == CB_MSG_IS_INTERNAL ? true : false;
	cbm.len = din.readUnsignedShort();

	cbm.data = new byte [ cbm.len ];
	din.read( cbm.data );

	return cbm;
    }

    public static byte [] encode( ExtMessage msg )
    {
	byte [] buf = new byte [ msg.len + HEADER_SIZE ];

	buf[ 0 ] = ( byte ) msg.type;
	buf[ 1 ] = ( byte ) msg.sId;
	buf[ 2 ] = ( byte ) msg.sInst;
	// buf

	return buf;
    }


    public static ExtMessage decodeHeader( byte [] buf )
    {
	// FIXME create and return CBMessage with only set header
	return null;
    }

    public String toString()
    {
	return "Sender:" + sId + "@" + sIP + ":" + sPort + "\n" + "Receiver:" + rId + "@" + rIP
		+ ":" + rPort + "\n";
    }
    
    public byte [] encode()
    {
	// FIXME encode of external message
	return null;
    }
}
